package mutil

import (
	"strconv"
	"strings"
)

const aBegin = 167772160
const aEnd = 184549375
const bBegin = 2886729728
const bEnd = 2887778303
const cBegin = 3232235520
const cEnd = 3232301055

var IP = &ip{}

type ip struct {
}

var cdn = []string{
	"www.189.cn",
	"shouji.189.cn",
	"image2.chinatelecom-ec.com",
	"image1.chinatelecom-ec.com",
}

func (domain *ip) IsInnerIp(ipAddr string) bool {
	ipNum := domain.getIpNum(ipAddr)
	isInnerIp := isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || ipAddr == "127.0.0.1"
	return isInnerIp
}

func (domain *ip) GetRealIP(xForwardedFor string, remoteAddr string, host string) string {
	clientIp := xForwardedFor
	if clientIp == "" || clientIp == "know" {
		if remoteAddr == "::1" {
			clientIp = "127.0.0.1"
		} else {
			clientIp = remoteAddr
		}
	}
	clientIps := strings.Split(clientIp, ",")
	if len(clientIps) <= 1 {
		return strings.Trim(clientIp, " ")
	}
	if domain.IsComeFromCDN(host) {
		if len(clientIps) >= 2 {
			return strings.Trim(clientIps[len(clientIps)-2], " ")
		}
	}
	return strings.Trim(clientIps[len(clientIps)-1], " ")

}
func (domain *ip) IsComeFromCDN(host string) bool {
	for _, val := range cdn {
		if strings.Contains(host, val) {
			return true
		}
	}
	return false

}

func (domain *ip) getIpNum(ipAddr string) int {
	ips := strings.Split(ipAddr, ".")
	a, _ := strconv.Atoi(ips[0])
	b, _ := strconv.Atoi(ips[1])
	c, _ := strconv.Atoi(ips[2])
	d, _ := strconv.Atoi(ips[3])
	return a*256*256*256 + b*256*256 + c*256 + d
}
func isInner(userIp int, begin int, end int) bool {
	return (userIp >= begin) && (userIp <= end)
}
